/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package com.iss.examsys.view;

import com.iss.examsys.common.EmsConstants;
import com.iss.examsys.ejb.ExamInstanceBean;
import com.iss.examsys.ejb.ExamPaperBean;
import com.iss.examsys.ejb.ExamTimerSessionBean;
import com.iss.examsys.ejb.UserBean;
import com.iss.examsys.entity.ExamInstance;
import com.iss.examsys.entity.ExamInstanceAnswer;
import com.iss.examsys.entity.ExamInstanceQuestion;
import com.iss.examsys.entity.ExamInstanceSection;
import com.iss.examsys.entity.ExamPaper;
import com.iss.examsys.entity.ExamSession;
import com.iss.examsys.entity.QuestionPart;
import com.iss.examsys.entity.Section;
import com.iss.examsys.entity.SectionQuestion;
import com.iss.examsys.entity.StudentExamStatus;
import com.iss.examsys.entity.User;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import org.primefaces.push.EventBus;
import org.primefaces.push.EventBusFactory;

/**
 *
 * @author Quek Ting Hong
 */
@ViewScoped
@Named
public class ExamInstanceView {

    private static final long serialVersionUID = 1L;
    
    private ExamInstance examInstance;
    private ExamInstanceQuestion currentQuestion;
    private boolean hasNextQuestion;
    private boolean hasPrevQuestion;
    private int questionNumber;
    private int sectionNumber;    
    private Integer id;
    private ExamSession examSession;
    
    
    @EJB ExamPaperBean examPaperBean;
    @EJB UserBean userBean;
    @EJB ExamTimerSessionBean examTimerSessionBean;
    @EJB ExamInstanceBean examInstanceBean;
    @Inject ExamStudentStatusView examStudentView;
    
    public ExamInstanceView() {          
    }
    
    public ExamInstance getExamInstance() {
        return examInstance;
    }

    public void setExamInstance(ExamInstance examInstance) {
        this.examInstance = examInstance;
    }

    public ExamInstanceQuestion getCurrentQuestion() {
        return currentQuestion;
    }

    public void setCurrentQuestion(ExamInstanceQuestion currentQuestion) {
        this.currentQuestion = currentQuestion;
    }

    public boolean isHasNextQuestion() {
        return hasNextQuestion;
    }

    public void setHasNextQuestion(boolean hasNextQuestion) {
        this.hasNextQuestion = hasNextQuestion;
    }

    public boolean isHasPrevQuestion() {
        return hasPrevQuestion;
    }

    public void setHasPrevQuestion(boolean hasPrevQuestion) {
        this.hasPrevQuestion = hasPrevQuestion;
    }

    public int getQuestionNumber() {
        return questionNumber;
    }

    public void setQuestionNumber(int questionNumber) {
        this.questionNumber = questionNumber;
    }

    public int getSectionNumber() {
        return sectionNumber;
    }

    public void setSectionNumber(int sectionNumber) {
        this.sectionNumber = sectionNumber;
    }

    public ExamSession getExamSession() {
        return examSession;
    }

    public void setExamSession(ExamSession examSession) {
        this.examSession = examSession;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    
    public void nextQuestion(){
        
        if(examInstance.getExamInstanceSectionList().get(sectionNumber).getExamInstanceQuestionList().size()==(questionNumber+1)){
            if(examInstance.getExamInstanceSectionList().size()>=(sectionNumber+1)){
                sectionNumber++;
                questionNumber = 0;
            }
        }else{
            questionNumber++;
        }
        
        currentQuestion = examInstance.getExamInstanceSectionList().get(sectionNumber).getExamInstanceQuestionList().get(questionNumber);
        
        hasNextQuestion = !(examInstance.getExamInstanceSectionList().size()==sectionNumber+1&&
                examInstance.getExamInstanceSectionList().get(examInstance.getExamInstanceSectionList().size()-1).getExamInstanceQuestionList().size()==questionNumber+1);
        
        hasPrevQuestion = !(sectionNumber==0&&questionNumber==0);
    }
    
    public void previousQuestion(){
        if(0>(questionNumber-1)){
            if(0>=(sectionNumber-1)){
                sectionNumber--;
                questionNumber = examInstance.getExamInstanceSectionList().get(sectionNumber).getExamInstanceQuestionList().size()-1;
            }
        }else{
            questionNumber--;
        }
        
        currentQuestion = examInstance.getExamInstanceSectionList().get(sectionNumber).getExamInstanceQuestionList().get(questionNumber);     
        
        hasNextQuestion = !(examInstance.getExamInstanceSectionList().size()==sectionNumber+1&&
                examInstance.getExamInstanceSectionList().get(examInstance.getExamInstanceSectionList().size()-1).getExamInstanceQuestionList().size()==questionNumber+1);
        
        hasPrevQuestion = !(sectionNumber==0&&questionNumber==0);
    }
    
    public void submitExamForm(){
        System.out.println(examInstance);
        
        //TODO to move to exam session deletion
//        examTimerSessionBean.cancelTimer("123");
                
        examInstanceBean.create(examInstance);
                
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
		HttpServletRequest req = (HttpServletRequest)ctx.getRequest();
                
        System.out.print(req.getRemoteUser());
        System.out.print(req.getUserPrincipal());
        System.out.print(FacesContext.getCurrentInstance().getExternalContext().getAuthType());
        
        User user = userBean.findByUserId(req.getRemoteUser());
        
        broadcastCompleteExam(user);
                
        try {
            FacesContext.getCurrentInstance().getExternalContext().redirect(FacesContext.getCurrentInstance().getExternalContext().getRequestContextPath()+"/faces/examsession/examFormSubmitted.xhtml");
        } catch (IOException ex) {
            Logger.getLogger(ExamInstanceView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public void initializeExamInstance(){       
        //TODO to be moved to create examsession
//        examTimerSessionBean.createTimer(10000);        
        ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
		HttpServletRequest req = (HttpServletRequest)ctx.getRequest();
                
        System.out.print(req.getRemoteUser());
        System.out.print(req.getUserPrincipal());
        System.out.print(FacesContext.getCurrentInstance().getExternalContext().getAuthType());
        
        User user = userBean.findByUserId(req.getRemoteUser());
        
        examInstance = createExamInstance(user);
        
        broadcastStartExam(user);
        
        questionNumber = 0;
        sectionNumber = 0;
        
        hasNextQuestion = examInstance.getExamInstanceSectionList().get(sectionNumber).getExamInstanceQuestionList().size()>1;
        currentQuestion = examInstance.getExamInstanceSectionList().get(sectionNumber).getExamInstanceQuestionList().get(questionNumber);
    }
    
    public void broadcastStartExam(User user){
        long examPaperId = examInstance.getExamSessionId().getId();
        StudentExamStatus status = new StudentExamStatus(user.getUserId()+"",examPaperId,0,"Seated for Exam");
        
        examStudentView.add(status);
        EventBus eventBus = EventBusFactory.getDefault().eventBus();
        eventBus.publish(EmsConstants.INVIGILATE_CHANNEL, status);
    }
    
    public void broadcastCompleteExam(User user){
        long examPaperId = examInstance.getExamSessionId().getId();
        StudentExamStatus status = new StudentExamStatus(user.getUserId()+"",examPaperId,0,"Submitted");        
                
        //TODO - to update student status
        examStudentView.update(status);
        EventBus eventBus = EventBusFactory.getDefault().eventBus();
        eventBus.publish(EmsConstants.INVIGILATE_CHANNEL, status);
    }
    
    public ExamInstance createExamInstance(User user){        
        System.out.print("Student take exam : "+user.getName());
        System.out.print("Exam paper id : "+getExamSession());
        
        ExamPaper examPaperTemplate = getExamSession().getExamPaperId();
        
        ExamInstance inst = new ExamInstance();
        
        inst.setExamSessionId(examSession);
        inst.setStudentId(user);
        
        List<ExamInstanceSection> instSecList = new ArrayList();
        
        Collection<Section> secTemplates = examPaperTemplate.getSectionCollection();
        
        
        //Section
        for(Section secTemp : secTemplates){
            ExamInstanceSection instSec = new ExamInstanceSection();
            instSec.setSectionId(secTemp);
            instSec.setExamSessionId(inst);
            List<ExamInstanceQuestion> instQuestionList = new ArrayList();
            
            Collection<SectionQuestion> secQuestionTemplates = secTemp.getSectionQuestionCollection();
            
            //Question
            for(SectionQuestion secQue : secQuestionTemplates){
                ExamInstanceQuestion instQ = new ExamInstanceQuestion();
                
                //TODO - AUTO
                
                
                //MANUAL
                instQ.setQuestionId(secQue.getQuestionId());
                instQ.setExamInstanceSectionId(instSec);
                List<ExamInstanceAnswer> answerList = new ArrayList();
                
                List<QuestionPart> questionPartTemplates = secQue.getQuestionId().getQuestionPartList();
                
                //Answer
                for(QuestionPart qPart : questionPartTemplates){
                    ExamInstanceAnswer answer = new ExamInstanceAnswer();
                    
                    answer.setQuestionPartId(qPart);
                    answer.setExamInstanceQuestionId(instQ);
                    answerList.add(answer);
                }
                
                instQ.setExamInstanceAnswerList(answerList);
                
                
                instQuestionList.add(instQ);
            }
            
            instSec.setExamInstanceQuestionList(instQuestionList);
            
            instSecList.add(instSec);
        }
        
        inst.setExamInstanceSectionList(instSecList);
        
        return inst;
    }
}
